using System.Collections.Generic;
using Headsight.BPMN2WF.BPMN.Model;
using Headsight.BPMN2WF.Testing.TestObjCtors;
using Headsight.BPMN2WF.Transformation.Transformers.Additions;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Rhino.Mocks;

namespace Headsight.BPMN2WF.Transformation.Transformers.NoGoodName
{
    [TestClass]
    public class BPMN2WFTransformationCacheTest : BPMN2WFTransformationDelegateBaseImplTestFixture<BPMN2WFTransformationCache>
    {
        private IDictionary<BPMNFlowNode, BPMNTransformationResult> _cache;
        private IBPMN2WFTransformationContext _ctx;
        private BPMNFlowNode _flowNode1;
        private BPMNFlowNode _flowNode2;

        protected override BPMN2WFTransformationCache CreateSut(IBPMN2WFTransformation @delegate)
        {
            _cache = new Dictionary<BPMNFlowNode, BPMNTransformationResult>();

            _ctx = MockRepository.GenerateStub<IBPMN2WFTransformationContext>();
            _flowNode1 = new BPMNFlowNodeCtor().WithId("1").Create();
            _flowNode2 = new BPMNFlowNodeCtor().WithId("2").Create();

            return new BPMN2WFTransformationCache(_cache, @delegate);
        }

        [TestMethod]
        public void Get_inco_result_existing()
        {
            var result1 = new BPMNTransformationResult(null, null);
            var result2 = new BPMNTransformationResult(null, null);
            _sut.Cache[_flowNode1] = result1;
            _sut.Cache[_flowNode2] = result2;

            Assert.AreSame(result1, _sut.Transform(_ctx, _flowNode1));
            Assert.AreSame(result2, _sut.Transform(_ctx, _flowNode2));
        }

        [TestMethod]
        public void Get_inco_result_not_yet_existing_delegates_to_delegates_and_caches_their_results()
        {
            var result1 = new BPMNTransformationResult(null, null);
            var result2 = new BPMNTransformationResult(null, null);
            _delegate.Expect(x => x.Transform(_ctx, _flowNode1)).Return(result1);
            _delegate.Expect(x => x.Transform(_ctx, _flowNode2)).Return(result2);

            Assert.AreSame(result1, _sut.Transform(_ctx, _flowNode1));
            Assert.AreSame(result1, _sut.Cache[_flowNode1]);

            Assert.AreSame(result2, _sut.Transform(_ctx, _flowNode2));
            Assert.AreSame(result2, _sut.Cache[_flowNode2]);
        }
    }
}